home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- PROGRAM: VNB.C
- WRITTEN BY: Robert Fenske, Jr. (rfenske@swri.edu)
- Southwest Research Institute
- Electromagnetics Division
- 6220 Culebra
- San Antonio, Texas 78238-5166
- CREATED: May 1994
- DESCRIPTION: This program is the VERDA Node Builder. It extracts
- the data from a DOOM-related PWAD, IWAD, or VERDA
- patch file and builds the BSP-related structures segs,
- subsectors, and nodes. It can build these structures
- for all the levels in the input file, or for a specific
- level found in the input file. The command line
- arguments are as follows:
- [-e#m#] <input file> [output file]
- where -e#m# specifies a particular level within the
- input level, input file is the input filename, and
- output file is the optional output filename. If no
- output file is specified, the input file is rewritten
- with the new data.
-
- This program has been compiled and run under SunOS
- using cc and under MS-DOS using DJGPP.
-
- There is a number of byte swapping calls used in the
- SunOS case; these calls are ugly, but necessary since
- the WAD files store data in little-endian order.
-
- DOOM is a trademark of id Software, Inc.
- ******************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "dmglobal.i"
-
- #define SOFTVER 1.050 /* software version */
- #define SOFTDATE "May 1994" /* software version date */
-
- #define RESOURCES_NEEDED ((1<<LINES)|(1<<VERTS))
-
- #define update_resource(s,d,n) \
- (blockfree(WInfo.data[WInfo.lvlndx+(s)]),\
- WInfo.data[WInfo.lvlndx+(s)] = (char *)(d),\
- WInfo.dir[WInfo.lvlndx+(s)].nbytes = \
- (long)(n)*datasize[s],\
- WInfo.changed[WInfo.lvlndx+(s)] = TRUE)
-
- global WAD_INFO WInfo; /* WAD information */
-
- local long datasize[] = { 1, sizeof(DOOM_VERT), sizeof(DOOM_LINE),
- sizeof(DOOM_SIDE), sizeof(DOOM_VERT),
- sizeof(DOOM_SEGS), sizeof(DOOM_SSECTOR),
- sizeof(DOOM_NODE), sizeof(DOOM_SECTOR),
- sizeof(DOOM_REJECT), sizeof(DOOM_BLOCKMAP)
- };
-
-
- /******************************************************************************
- ROUTINE: main(ac,av)
- WRITTEN BY: Robert Fenske, Jr.
- CREATED: May 1994
- DESCRIPTION: This routine processes the command line arguments
- and executes the appropriate build function.
- ******************************************************************************/
- main(ac,av)
- int ac;
- char *av[];
- {
- char *ifile = NULL, *ofile = NULL; /* input/output filenames */
- boolean help = FALSE; /* whether to display help */
- boolean good = FALSE; /* whether read/write worked */
- boolean rewrite; /* whether input rewritten */
- boolean wad = FALSE, /* (I/P)WAD file flag */
- patch = FALSE; /* VERDA patch file flag */
- int epdo = 0, mpdo = 0; /* specific ep/map to do */
- register FILE *ifp, *ofp; /* input/output file ptrs */
- register int i;
-
- setbuf(stdout,(char *)NULL); /* make stdout unbuffered */
- printf("\n\t\t\t\tVERDA Node Builder\n");
- printf("\tVersion %5.3lf of %s by Robert Fenske, Jr (rfenske@swri.edu)\n",
- SOFTVER,SOFTDATE);
- for (i = 1; i < ac; i++) { /* scan all arguments */
- if (av[i][0] == '-') {
- if (2 != sscanf(av[i],"-e%1dm%1d",&epdo,&mpdo)) help = TRUE;
- }else if (ifile == NULL)
- ifile = ofile = av[i];
- else
- ofile = av[i];
- }
- if (ifile == NULL || help) { /* show now to do corectly */
- printf("\n%s [-e#m#] <input file> [output file]\n\n",av[0]);
- printf("%*s -e#m# specify level to process;\n",
- strlen(av[0]),"");
- printf("%*s otherwise does all levels\n",
- strlen(av[0]),"");
- printf("%*s <input file> PWAD, IWAD, or VERDA patch file\n",
- strlen(av[0]),"");
- printf("%*s <output file> output file; if none specified,\n",
- strlen(av[0]),"");
- printf("%*s input file is rewritten\n",
- strlen(av[0]),"");
- return 1;
- }
- ifp = fopen(ifile,"rb"); /* open input file */
- if (ifp == NULL) {
- fprintf(stderr,"\nunable to open %s for reading\n",ifile);
- return 1;
- }
- fread((char *)&WInfo.head,sizeof WInfo.head,1,ifp);
- if (strncmp(WInfo.head.ident,"PWAD",4) == 0 ||
- strncmp(WInfo.head.ident,"IWAD",4) == 0) wad = TRUE;
- rewind(ifp);
- if (2 == fscanf(ifp," %d %d %*d %*lf",&WInfo.ep,&WInfo.mp)) patch = TRUE;
- if (!wad && !patch) { /* not a valid file */
- fprintf(stderr,"\n%s is not a PWAD, IWAD, nor VERDA patch file\n",ifile);
- return 1;
- }
- rewrite = !patch && ifile == ofile; /* whether input rewritten */
- WInfo.lvlndx = -ALL;
- do { /* process file until done */
- printf("\nReading %s file %s...",patch?"patch":"WAD",ifile);
- if (patch) good = patch_read(ifp,epdo,mpdo,RESOURCES_NEEDED);
- else if (wad) good = wad_read(ifp,epdo,mpdo,RESOURCES_NEEDED);
- if (good) { /* process new level data */
- DOOM_LINE *lines = Lines;
- DOOM_VERT *verts = Verts;
- DOOM_SEGS *segs = Segs;
- DOOM_SSECTOR *ssecs = Ssecs;
- DOOM_NODE *nodes = Nodes;
- DOOM_BLOCKMAP *blockmaps = Blockmaps;
- printf("done\n");
- printf("Building BSP Tree for level E%1dM%1d...",WInfo.ep,WInfo.mp);
- nodes_make(&nodes,&NNodes,&ssecs,&NSsecs,&segs,&NSegs,&verts,&NVerts,
- &lines,&NLines);
- update_resource(VERTS,verts,NVerts);
- update_resource(SEGS,segs,NSegs);
- update_resource(SSECTS,ssecs,NSsecs);
- update_resource(NODES,nodes,NNodes);
- printf("%d nodes, %d segs \n",NNodes,NSegs);
- printf("Building BLOCKMAP for level E%1dM%1d...",WInfo.ep,WInfo.mp);
- NBlockmaps = blockmap_make(&blockmaps,Lines,NLines,Verts);
- for (i = 0; i < NBlockmaps; i++)
- blockmaps[i] = bswapw(blockmaps[i]);
- update_resource(BLKMAPS,blockmaps,NBlockmaps);
- printf("done\n");
- }else if (WInfo.lvlndx >= 0) /* no more in file */
- printf("no more levels\n");
- else /* oops: bogus data */
- printf("failed\n");
- if (good) { /* if processed, write it */
- ofp = fopen(ofile,rewrite?"r+b":"wb");
- if (ofp == NULL) {
- fprintf(stderr,"unable to open %s for writing\n",ofile);
- return 1;
- }
- printf("Writing %s file %s...",patch?"patch":"WAD",ofile);
- if (patch) good = patch_write(ifp,ofp,rewrite);
- else if (wad) good = wad_write(ifp,ofp,rewrite);
- fclose(ofp);
- if (good) printf("done\n");
- else printf("failed\n");
- }
- } while (good);
- fclose(ifp);
- return 0; /* everything is okay */
- }
-
-
- /******************************************************************************
- ROUTINE: patch_read(patch,epdo,mpdo,resources_needed)
- WRITTEN BY: Robert Fenske, Jr.
- CREATED: May 1994
- DESCRIPTION: This routine reads a VERDA patch file. It reads the
- file twice; the first time is to obtain the sizes of
- each of the resources. The input resources_needed is
- ignored--everything in the patch file is read. Also,
- only one level's data is stored in a patch file.
- ******************************************************************************/
- patch_read(patch,epdo,mpdo,resources_needed)
- register FILE *patch;
- int epdo, mpdo, resources_needed;
- {
- char str[256];
- int type;
- int i = 0;
- register int t = 0, l = 0, s = 0, v = 0, c = 0;
-
- WInfo.lvlndx += ALL;
- if (WInfo.lvlndx != 0) /* can't do more than one */
- return FALSE; /* level with patch file */
- WInfo.dir = blockmem(DIR_ENTRY,WInfo.head.count = ALL);
- WInfo.data = blockmem(char *,WInfo.head.count);
- WInfo.changed = blockmem(boolean,WInfo.head.count);
- WInfo.count = blockmem(int,WInfo.head.count);
- sprintf(WInfo.dir[WInfo.lvlndx+MAINS].name,"E%1dM%1d",WInfo.ep,WInfo.mp);
- rewind(patch);
- while (fgets(str,sizeof str,patch) != NULL) {
- if (i == 0) {
- i = sscanf(str," %d %d %d %lf",&WInfo.ep,&WInfo.mp,&type,&WInfo.ver);
- if (i && epdo && mpdo && (WInfo.mp+1 != epdo || WInfo.ep+1 != mpdo))
- return FALSE; /* doesn't match desired */
- continue; /* level */
- }
- switch (type) {
- bcase THINGS: i = str[0] != '%'; if (i) t++;
- bcase LINES: i = str[0] != '%'; if (i) l++;
- bcase SIDES: i = str[0] != '%'; if (i) s++;
- bcase VERTS: i = str[0] != '%'; if (i) v++;
- bcase SEGS: i = str[0] != '%';
- bcase SSECTS: i = str[0] != '%';
- bcase NODES: i = str[0] != '%';
- bcase SECTS: i = str[0] != '%'; if (i) c++;
- }
- }
- WInfo.data[THINGS] = (char *)blockmem(DOOM_THING, WInfo.count[THINGS] = t);
- WInfo.data[LINES] = (char *)blockmem(DOOM_LINE, WInfo.count[LINES] = l);
- WInfo.data[SIDES] = (char *)blockmem(DOOM_SIDE, WInfo.count[SIDES] = s);
- WInfo.data[VERTS] = (char *)blockmem(DOOM_VERT, WInfo.count[VERTS] = v);
- WInfo.data[SECTS] = (char *)blockmem(DOOM_SECTOR,WInfo.count[SECTS] = c);
- i = t = l = s = v = c = 0;
- rewind(patch);
- while (fgets(str,sizeof str,patch) != NULL) {
- if (i == 0) {
- i = sscanf(str," %d %d %d %lf",&WInfo.ep,&WInfo.mp,&type,&WInfo.ver);
- continue;
- }
- switch (type) {
- bcase THINGS: /* THINGS */
- i = sscanf(str,"%*d %4hx %4hx %3hd %4hx %4hx",
- &Things[t].x,&Things[t].y,&Things[t].angle,
- &Things[t].flag,&Things[t].item);
- if (i==5) t++;
- bcase LINES: /* LINES */
- i = sscanf(str,"%*d %4hx %4hx %4hx %4hx %4hx %4hx %4hx",
- &Lines[l].fndx,&Lines[l].tndx,&Lines[l].flag,
- &Lines[l].action_flag,&Lines[l].sect_tag,
- &Lines[l].rsidndx,&Lines[l].lsidndx);
- if (i==7) l++;
- bcase SIDES: /* SIDES */
- i = sscanf(str,"%*d %4hx %4hx %8c %8c %8c %4hx",
- &Sides[s].image_xoff,&Sides[s].image_yoff,
- Sides[s].lowwall,Sides[s].highwall,Sides[s].fullwall,
- &Sides[s].sectndx);
- if (i==6) s++; else i = 0;
- bcase VERTS: /* VERTEXES */
- i = sscanf(str,"%*d %4hx %4hx",&Verts[v].x,&Verts[v].y);
- if (i==2) v++;
- bcase SEGS: i = str[0] != '%'; /* SEGS */
- bcase SSECTS: i = str[0] != '%'; /* SSECTORS */
- bcase NODES: i = str[0] != '%'; /* NODES */
- bcase SECTS: /* SECTORS */
- i = sscanf(str,"%*d %4hx %4hx %8c %8c %4hx %4hx %4hx",
- &Sects[c].floor_ht,&Sects[c].ceil_ht,Sects[c].floor_desc,
- Sects[c].ceil_desc,&Sects[c].light_lvl,&Sects[c].property,
- &Sects[c].line_tag);
- if (i==7) c++; else i = 0;
- }
- }
- NThings = t;
- NLines = l;
- NSides = s;
- NVerts = v;
- NSects = c;
- WInfo.ep++; WInfo.mp++;
- return TRUE;
- }
-
-
- /******************************************************************************
- ROUTINE: patch_write(rpatch,wpatch,rewrite)
- WRITTEN BY: Robert Fenske, Jr.
- CREATED: May 1994
- DESCRIPTION: This routine writes a VERDA patch file. Only one
- level's data is stored in a patch file.
- ******************************************************************************/
- patch_write(rpatch,wpatch,rewrite)
- register FILE *rpatch, *wpatch;
- boolean rewrite;
- {
- register int i;
-
- if (WInfo.lvlndx != 0) /* can't do more than one */
- return FALSE; /* level with patch file */
- fprintf(wpatch,"%d %d %d %4.2lf\n",--WInfo.ep,--WInfo.mp,THINGS,WInfo.ver);
- for (i = 0; i < NThings; i++)
- fprintf(wpatch,"%03d %04x %04x %03d %04x %02x\n",i,
- (ushort)Things[i].x,(ushort)Things[i].y,Things[i].angle,
- Things[i].flag,Things[i].item);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,LINES,WInfo.ver);
- for (i = 0; i < NLines; i++)
- fprintf(wpatch,"%03d %04x %04x %04x %04x %04x %04x %04x\n",i,
- Lines[i].fndx,Lines[i].tndx,
- (ushort)Lines[i].flag,(ushort)Lines[i].action_flag,
- (ushort)Lines[i].sect_tag,
- (ushort)Lines[i].rsidndx,(ushort)Lines[i].lsidndx);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,SIDES,WInfo.ver);
- for (i = 0; i < NSides; i++)
- fprintf(wpatch,"%03d %04x %04x %-8.8s %-8.8s %-8.8s %03x\n",i,
- (ushort)Sides[i].image_xoff,(ushort)Sides[i].image_yoff,
- Sides[i].lowwall,Sides[i].highwall,Sides[i].fullwall,
- Sides[i].sectndx);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,VERTS,WInfo.ver);
- for (i = 0; i < NVerts; i++)
- fprintf(wpatch,"%03d %04x %04x\n",i,
- (ushort)Verts[i].x,(ushort)Verts[i].y);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,SEGS,WInfo.ver);
- for (i = 0; i < NSegs; i++)
- fprintf(wpatch,"%03d %04x %04x %04x %04x %04x %04x\n",i,
- Segs[i].fndx,Segs[i].tndx,(ushort)Segs[i].angle,
- Segs[i].lndx,Segs[i].sndx,Segs[i].loffset);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,SSECTS,WInfo.ver);
- for (i = 0; i < NSsecs; i++)
- fprintf(wpatch,"%03d %04x %04x\n",i,
- Ssecs[i].count,Ssecs[i].sndx);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,NODES,WInfo.ver);
- for (i = 0; i < NNodes; i++)
- fprintf(wpatch,"%03d \
- %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",i,
- (ushort)Nodes[i].x,(ushort)Nodes[i].y,
- (ushort)Nodes[i].xdel,(ushort)Nodes[i].ydel,
- (ushort)Nodes[i].rymax,(ushort)Nodes[i].rymin,
- (ushort)Nodes[i].rxmin,(ushort)Nodes[i].rxmax,
- (ushort)Nodes[i].lymax,(ushort)Nodes[i].lymin,
- (ushort)Nodes[i].lxmin,(ushort)Nodes[i].lxmax,
- (ushort)Nodes[i].nndx[0],(ushort)Nodes[i].nndx[1]);
- fprintf(wpatch,"%%\n%d %d %d %4.2lf\n",WInfo.ep,WInfo.mp,SECTS,WInfo.ver);
- for (i = 0; i < NSects; i++)
- fprintf(wpatch,"%03d %04x %04x %-8.8s %-8.8s %04x %04x %04x\n",i,
- (ushort)Sects[i].floor_ht,(ushort)Sects[i].ceil_ht,
- Sects[i].floor_desc,Sects[i].ceil_desc,
- Sects[i].light_lvl,Sects[i].property,(ushort)Sects[i].line_tag);
- return TRUE;
- }
-
-
- /******************************************************************************
- ROUTINE: wad_bswap(resource,type)
- WRITTEN BY: Robert Fenske, Jr.
- CREATED: May 1994
- DESCRIPTION: This routine swaps the bytes in the short integer
- fields of the various resources. This is necessary
- since the data files store integers in Intel little-
- endian order, while all real systems use big-endian
- order.
- ******************************************************************************/
- void wad_bswap(resource,type)
- int resource, type;
- {
- #if defined(BSWAP) /* non-Intel only */
- int cnt = WInfo.dir[resource].nbytes/datasize[type];/* # items */
- short *data = (short *)WInfo.data[resource]; /* where data is */
- register int d, w;
-
- if (data != NULL)
- switch (type) {
- bcase THINGS:
- case LINES:
- case VERTS:
- case SEGS:
- case SSECTS:
- case NODES:
- for (d = 0; d < cnt; d++)
- for (w = 0; w < datasize[type]/2; w++)
- data[d*datasize[type]/2+w] = bswapw(data[d*datasize[type]/2+w]);
- bcase SIDES: /* only swap integer fields */
- for (d = 0; d < cnt; d++) {
- Sides[d].image_xoff = bswapw(Sides[d].image_xoff);
- Sides[d].image_yoff = bswapw(Sides[d].image_yoff);
- Sides[d].sectndx = bswapw(Sides[d].sectndx);
- }
- bcase SECTS: /* only swap integer fields */
- for (d = 0; d < cnt; d++) {
- Sects[d].floor_ht = bswapw(Sects[d].floor_ht);
- Sects[d].ceil_ht = bswapw(Sects[d].ceil_ht);
- Sects[d].light_lvl = bswapw(Sects[d].light_lvl);
- Sects[d].property = bswapw(Sects[d].property);
- Sects[d].line_tag = bswapw(Sects[d].line_tag);
- }
- }
- #endif
- }
-
-
- /******************************************************************************
- ROUTINE: wad_read(wad,epdo,mpdo,resources_needed)
- WRITTEN BY: Robert Fenske, Jr.
- CREATED: May 1994
- DESCRIPTION: This routine reads a WAD file. It reads the next
- unprocessed level if epdo and mpdo are zero, or
- reads the level referenced by epdo and mpdo.
- resources_needed governs which resources from the
- level are actually read. The WAD file header is read,
- then the resource directory, then the requested
- resources. The resource directory is held in two
- locations--one for modification and one to preserve
- the original directory.
- ******************************************************************************/
- wad_read(wad,epdo,mpdo,resources_needed)
- register FILE *wad;
- int epdo, mpdo, resources_needed;
- {
- register int e, i;
-
- rewind(wad);
- fread((char *)&WInfo.head,sizeof WInfo.head,1,wad);
- WInfo.head.count = bswapl(WInfo.head.count);
- WInfo.head.offset = bswapl(WInfo.head.offset);
- WInfo.origdir = blockmem(DIR_ENTRY,WInfo.head.count);
- WInfo.dir = blockmem(DIR_ENTRY,WInfo.head.count);
- WInfo.data = blockmem(char *,WInfo.head.count);
- WInfo.changed = blockmem(boolean,WInfo.head.count);
- WInfo.count = blockmem(int,WInfo.head.count);
- fseek(wad,WInfo.head.offset,0L); /* read directory */
- fread((char *)WInfo.origdir,(unsigned)WInfo.head.count,
- sizeof(*WInfo.origdir),wad);
- for (e = 0; e < WInfo.head.count; e++) {
- WInfo.dir[e] = WInfo.origdir[e];
- WInfo.dir[e].offset =
- WInfo.origdir[e].offset = bswapl(WInfo.origdir[e].offset);
- WInfo.dir[e].nbytes =
- WInfo.origdir[e].nbytes = bswapl(WInfo.origdir[e].nbytes);
-
- }
- for (e = 0; e < WInfo.lvlndx; e++) blockfree(WInfo.data[e]);
- for (e = WInfo.lvlndx+ALL; e < WInfo.head.count; e++)
- if (2 == sscanf(WInfo.dir[e].name,"E%1dM%1d",&WInfo.ep,&WInfo.mp) &&
- (epdo == 0 && mpdo == 0 || epdo == WInfo.ep && mpdo == WInfo.mp))
- break; /* found level */
- if (e >= WInfo.head.count) /* no more levels to process */
- return FALSE;
- WInfo.lvlndx = e; /* this map's info is here */
- for (i = 0; i < ALL; i++) {
- if (resources_needed & (1<<i)) { /* get requested resources */
- WInfo.data[e+i] = blockmem(char,WInfo.dir[e+i].nbytes);
- fseek(wad,WInfo.dir[e+i].offset,0L);
- fread(WInfo.data[e+i],(unsigned)WInfo.dir[e+i].nbytes,1,wad);
- wad_bswap(e+i,i);
- }else
- WInfo.data[e+i] = NULL; /* no data for resource */
- WInfo.count[e+i] = WInfo.dir[e+i].nbytes/datasize[i];
- }
- return TRUE;
- }
-
-
- /******************************************************************************
- ROUTINE: wad_write(rwad,wwad,rewrite)
- WRITTEN BY: Robert Fenske, Jr.
- CREATED: May 1994
- DESCRIPTION: This routine writes a WAD file. If rewrite is TRUE,
- then the input file is being rewritten with the new
- data; otherwise, a new file is written. The resources
- are written out in reverse order; this easily handles
- the case where the input file is being rewritten and
- some of the resources have grown in size. Also in
- the rewrite case, if a resource is smaller than before,
- it is marked with the new smaller size but the
- following resources are not "shifted down". Thus there
- will be some parts of the file that will be unused.
- ******************************************************************************/
- wad_write(rwad,wwad,rewrite)
- register FILE *rwad, *wwad;
- boolean rewrite;
- {
- long dir_offset; /* new directory offset */
- char *buf; /* temporary data buffer */
- register int e;
-
- for (e = 0; e < ALL; e++) wad_bswap(WInfo.lvlndx+e,e);
- for (e = 1; e < WInfo.head.count; e++) { /* compute new directory */
- if (!rewrite || WInfo.origdir[e-1].offset == 0)
- WInfo.dir[e].offset = WInfo.dir[e-1].offset + WInfo.dir[e-1].nbytes;
- else
- WInfo.dir[e].offset = WInfo.dir[e-1].offset +
- max(WInfo.dir[e-1].nbytes,
- WInfo.origdir[e].offset-
- WInfo.origdir[e-1].offset);
- }
- for (e = WInfo.head.count-1; e >= WInfo.lvlndx; e--) {/* write resources */
- if (WInfo.changed[e]) {
- fseek(wwad,WInfo.dir[e].offset,0L);
- fwrite(WInfo.data[e],(unsigned)WInfo.dir[e].nbytes,1,wwad);
- WInfo.changed[e] = FALSE;
- }else if (!rewrite || WInfo.origdir[e].offset != WInfo.dir[e].offset) {
- buf = blockmem(char,WInfo.origdir[e].nbytes);
- fseek(rwad,WInfo.origdir[e].offset,0L);
- fread(buf,(unsigned)WInfo.origdir[e].nbytes,sizeof(*buf),rwad);
- fseek(wwad,WInfo.dir[e].offset,0L);
- fwrite(buf,(unsigned)WInfo.origdir[e].nbytes,sizeof(*buf),wwad);
- blockfree(buf);
- }
- }
- blockfree(WInfo.origdir); /* done with original dir */
- dir_offset = WInfo.dir[WInfo.head.count-1].offset +
- WInfo.dir[WInfo.head.count-1].nbytes;
- for (e = 0; e < WInfo.head.count; e++) {
- WInfo.dir[e].offset = bswapl(WInfo.dir[e].offset);
- WInfo.dir[e].nbytes = bswapl(WInfo.dir[e].nbytes);
- }
- fseek(wwad,dir_offset,0L); /* write new directory */
- fwrite(WInfo.dir,(unsigned)WInfo.head.count,sizeof(*WInfo.dir),wwad);
- WInfo.head.offset = bswapl(dir_offset);
- WInfo.head.count = bswapl(WInfo.head.count);
- fseek(wwad,0L,0L);
- fwrite(&WInfo.head,sizeof(WInfo.head),1,wwad);/* write new header */
- blockfree(WInfo.dir); /* done with these */
- blockfree(WInfo.data);
- blockfree(WInfo.changed);
- blockfree(WInfo.count);
- return TRUE;
- }
-